# contextlib
# 任何对象，只要正确实现了上下文管理__enter__和__exit__这两个方法就可以用于with语句
class Query(object):
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('Begin')
        return self
    
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type:
            print('Error')
        else:
            print('End')
    
    def query(self):
        print('Query info about %s...' % self.name)
        
with Query('Bob') as q:
    q.query()
print('-------------------------')
from contextlib import contextmanager

class Query(object):
    def __init__(self, name):
        self.name = name

    def query(self):
        print('Query info about %s...' % self.name)
        
# @contextmanager
# 这个decorator接受一个generator，用yield语句把with ... as var把变量输出出去
@contextmanager
def create_query(name):
    print('Begin')
    q = Query(name)
    yield q
    print('End')
# contextlib 
with create_query('Bob') as q:
    q.query()
print('-------------------------')   
# @closing
# 如果一个对象没有实现上下文，我们就不能把它用于with语句。这个时候，可以用closing()来把该对象变为上下文对象
# @contextmanager
# def closing(thing):
#     try:
#         yield thing
#     finally:
#         thing.close()
from contextlib import closing
class MyFile():
    def close(self):
        print('File closed')
f1 = MyFile()
with closing(f1) as f:
    print('Using file')